package
{
	import flash.display.*;
	import flash.errors.IllegalOperationError;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	
	public class DeleteTool extends CursorTool
	{		
		// private objects
		private var drawPoints:Array = null;
		private var overDrawPoint:DrawPoint = null;
		private var drawSegments:Array = null;
		private var overDrawSegment:DrawSegment = null;
		private var selectedDrawPoint:DrawPoint = null;
		private var selectedDrawSegment:DrawSegment = null;
		// private vars
		private var _state:String;
		private var _freePointsRemaining:int;
		public function get freePointsRemaining():int{return _freePointsRemaining;}
		override public function get components():Array
		{
			if (selectedDrawPoint != null)
			{
				return new Array(selectedDrawPoint);
			} else if (selectedDrawSegment != null)
			{
				return new Array(selectedDrawSegment);
			}	else
			{
				return null;
			}
		}
		
		
		public function DeleteTool(drawPoints:Array, drawSegments:Array, freePoints:int=-1)
		{
			super(this);
			this.drawPoints = drawPoints;
			this.drawSegments = drawSegments;
			this._freePointsRemaining = freePoints; 
			this.mouseEnabled = false;
			this.mouseChildren = false;
			this.addEventListener(Event.ADDED, handleAdded);
		}
		private function handleAdded(event:Event):void
		{
			this.removeEventListener(Event.ADDED, handleAdded);
			_state = "delete";
			drawCursor();
			// go through each point and add event listener
			for each (var p:DrawPoint in drawPoints)
			{
				p.mouseEnabled = true;
				if(!p.hasEventListener(MouseEvent.MOUSE_OVER)) p.addEventListener(MouseEvent.MOUSE_OVER, handleMouseOverPoint);
			}
			for each (var s:DrawSegment in drawSegments)
			{
				s.mouseEnabled = true;
				if(!s.hasEventListener(MouseEvent.MOUSE_OVER)) s.addEventListener(MouseEvent.MOUSE_OVER, handleMouseOverSegment);
			}
			this.addEventListener(Event.REMOVED, handleRemoved);			
		}
		////////////////////////////// INTERACTIVITY //////////////////////////////
		/** Mouse over should work for all points to highlight except currently selected, unless allow disconnected */
		private function handleMouseOverPoint(event:MouseEvent):void
		{
			overDrawPoint = DrawPoint(event.currentTarget);
			overDrawPoint.removeEventListener(MouseEvent.MOUSE_OVER, handleMouseOverPoint);
			if (!overDrawPoint.pinned && !overDrawPoint.fixed)
			{
				overDrawPoint.addEventListener(MouseEvent.CLICK, handleClickPoint);	
				_state = "delete-yes";
			} else 
			{
				_state = "delete-no";	
			}
			drawCursor();
			overDrawPoint.addEventListener(MouseEvent.MOUSE_OUT, handleMouseOutPoint);
		}
		private function handleMouseOutPoint(event:MouseEvent):void
		{
			overDrawPoint.removeEventListener(MouseEvent.MOUSE_OUT, handleMouseOutPoint);
			overDrawPoint.removeEventListener(MouseEvent.CLICK, handleClickPoint);
			_state = "delete";
			drawCursor();
			overDrawPoint.addEventListener(MouseEvent.MOUSE_OVER, handleMouseOverPoint);
			overDrawPoint = null;
		}
		/** The click handler either adds a new segment if another point is selected or selects this point if no point is selected */
		private function handleClickPoint(event:MouseEvent):void
		{
			overDrawPoint.removeEventListener(MouseEvent.CLICK, handleClickPoint);
			
			// (double-check) make sure this point is not pinned
			if (!overDrawPoint.pinned && !overDrawPoint.fixed)
			{ 
				// remove listener
				overDrawPoint.removeEventListener(MouseEvent.MOUSE_OUT, handleMouseOutPoint);
				selectedDrawPoint = overDrawPoint; // to keep track of the last deleted point
				DrawingPanel(parent).deletePoint(overDrawPoint);
				overDrawPoint = null;
				_state = "delete";
				drawCursor();
			
				//this.dispatchEvent(new Event(Event.COMPLETE));
				if (_freePointsRemaining >= 0) _freePointsRemaining++;
				GeometryGameItem(parent.parent).processCommand("delete", "in_progress", this,new Array(selectedDrawPoint, freePointsRemaining));
			}	
		}
		/** Mouse over should work for all points to highlight except currently selected, unless allow disconnected */
		private function handleMouseOverSegment(event:MouseEvent):void
		{
			if (overDrawPoint == null)
			{
				overDrawSegment = DrawSegment(event.currentTarget);
				if (overDrawSegment.fixed)
				{
					_state = "delete-no";
					drawCursor();
				} else
				{
					overDrawSegment.removeEventListener(MouseEvent.MOUSE_OVER, handleMouseOverSegment);
					overDrawSegment.enhance = true;
					overDrawSegment.addEventListener(MouseEvent.CLICK, handleClickSegment);	
					_state = "delete-yes";
					drawCursor();
					overDrawSegment.addEventListener(MouseEvent.MOUSE_OUT, handleMouseOutSegment);
				}
			}
		}
		private function handleMouseOutSegment(event:MouseEvent):void
		{
			overDrawSegment.removeEventListener(MouseEvent.MOUSE_OUT, handleMouseOutSegment);
			overDrawSegment.removeEventListener(MouseEvent.CLICK, handleClickSegment);
			overDrawSegment.enhance = false;
			_state = "delete";
			drawCursor();
			overDrawSegment.addEventListener(MouseEvent.MOUSE_OVER, handleMouseOverSegment);
			overDrawSegment = null;
		}
		/** The click handler adds a new point and splits the segment into two new segments, removing the old segment */
		private function handleClickSegment(event:MouseEvent):void
		{
			overDrawSegment.removeEventListener(MouseEvent.CLICK, handleClickSegment);
			if (DrawingPanel(parent).deleteSegment(overDrawSegment, false))
			{
				selectedDrawSegment = overDrawSegment;
				GeometryGameItem(parent.parent).processCommand("delete", "in_progress", this,new Array(overDrawSegment, freePointsRemaining));
			}
		}
		/** Process moves cursor, looks for out of bounds */
		override public function process(point:Point):void
		{			
			this.x = point.x;
			this.y = point.y;
			
		}
		private function drawCursor():void
		{
			var pointsize:Number = DrawPoint.POINT_SIZE*ShapeProductionTask.unit;
			var enhancedsize:Number = DrawPoint.ENHANCED_SIZE*ShapeProductionTask.unit;
			
			switch(_state)
			{
				case "delete":
					this.graphics.clear();
					this.graphics.lineStyle(2,0x000000);
					this.graphics.moveTo(-pointsize/2*Math.sqrt(2)/2,-pointsize/2*Math.sqrt(2)/2);
					this.graphics.lineTo(pointsize/2*Math.sqrt(2)/2,pointsize/2*Math.sqrt(2)/2);
					this.graphics.moveTo(pointsize/2*Math.sqrt(2)/2,-pointsize/2*Math.sqrt(2)/2);
					this.graphics.lineTo(-pointsize/2*Math.sqrt(2)/2,pointsize/2*Math.sqrt(2)/2);
					break;
				case "delete-yes":
					this.graphics.clear();
					this.graphics.lineStyle(3,0x000000);
					this.graphics.moveTo(-enhancedsize/2*Math.sqrt(2)/2,-enhancedsize/2*Math.sqrt(2)/2);
					this.graphics.lineTo(enhancedsize/2*Math.sqrt(2)/2,enhancedsize/2*Math.sqrt(2)/2);
					this.graphics.moveTo(enhancedsize/2*Math.sqrt(2)/2,-enhancedsize/2*Math.sqrt(2)/2);
					this.graphics.lineTo(-enhancedsize/2*Math.sqrt(2)/2,enhancedsize/2*Math.sqrt(2)/2);
					this.graphics.lineStyle(1,0xFFFF0);
					this.graphics.moveTo(-enhancedsize/2*Math.sqrt(2)/2,-enhancedsize/2*Math.sqrt(2)/2);
					this.graphics.lineTo(enhancedsize/2*Math.sqrt(2)/2,enhancedsize/2*Math.sqrt(2)/2);
					this.graphics.moveTo(enhancedsize/2*Math.sqrt(2)/2,-enhancedsize/2*Math.sqrt(2)/2);
					this.graphics.lineTo(-enhancedsize/2*Math.sqrt(2)/2,enhancedsize/2*Math.sqrt(2)/2);
					break;
				case "delete-no":
					this.graphics.clear();
					this.graphics.lineStyle(2,0xFF0000);
					this.graphics.moveTo(-pointsize/2*Math.sqrt(2)/2,-pointsize/2*Math.sqrt(2)/2);
					this.graphics.lineTo(pointsize/2*Math.sqrt(2)/2,pointsize/2*Math.sqrt(2)/2);
					this.graphics.moveTo(pointsize/2*Math.sqrt(2)/2,-pointsize/2*Math.sqrt(2)/2);
					this.graphics.lineTo(-pointsize/2*Math.sqrt(2)/2,pointsize/2*Math.sqrt(2)/2);
					break;
			}
		}
		/** On removal unproject and unoutline */
		private function handleRemoved(event:Event):void
		{
			this.removeEventListener(Event.REMOVED, handleRemoved);
			if (overDrawPoint != null)
			{
				overDrawPoint.enhance = false;
				overDrawPoint.highlight = false;
			}
			if (selectedDrawPoint != null)
			{
				selectedDrawPoint.enhance = false;
				selectedDrawPoint.highlight = false;
			}	
			if (overDrawSegment != null)
			{
				overDrawSegment.enhance = false;
			}
			if (selectedDrawSegment != null)
			{
				selectedDrawSegment.enhance = false;
			}	
			for each (var p:DrawPoint in drawPoints)
			{
				if(p.hasEventListener(MouseEvent.MOUSE_OVER)) p.removeEventListener(MouseEvent.MOUSE_OVER, handleMouseOverPoint);
				if(p.hasEventListener(MouseEvent.MOUSE_OUT)) p.removeEventListener(MouseEvent.MOUSE_OUT, handleMouseOutPoint);
				if(p.hasEventListener(MouseEvent.CLICK)) p.removeEventListener(MouseEvent.CLICK, handleClickPoint);
				p.mouseEnabled = false;
			}
			for each (var s:DrawSegment in drawSegments)
			{
				if(s.hasEventListener(MouseEvent.MOUSE_OVER)) s.removeEventListener(MouseEvent.MOUSE_OVER, handleMouseOverSegment);
				if(s.hasEventListener(MouseEvent.MOUSE_OUT)) s.removeEventListener(MouseEvent.MOUSE_OUT, handleMouseOutSegment);
				if(s.hasEventListener(MouseEvent.CLICK)) s.removeEventListener(MouseEvent.CLICK, handleClickSegment);
				s.mouseEnabled = false;
			}
		}
	}
}